<?php

declare(strict_types=1);

namespace app\service\misc;

class GeoRegionService
{
    private array $treeCache = [];

    public function tree(): array
    {
        if ($this->treeCache !== []) {
            return $this->treeCache;
        }

        $file = $this->resolveFilePath();
        if (!is_file($file)) {
            return [];
        }

        $data = json_decode(file_get_contents($file), true);
        if (!is_array($data)) {
            return [];
        }

        $this->treeCache = $this->buildTree($data, [], [], 1);
        return $this->treeCache;
    }

    private function buildTree(array $nodes, array $codePath, array $namePath, int $level): array
    {
        $result = [];
        foreach ($nodes as $node) {
            if (!isset($node['code'], $node['name'])) {
                continue;
            }

            $code = (string) $node['code'];
            $name = (string) $node['name'];

            $currentCodePath = [...$codePath, $code];
            $currentNamePath = [...$namePath, $name];

            $children = [];
            if (!empty($node['children']) && is_array($node['children'])) {
                $children = $this->buildTree($node['children'], $currentCodePath, $currentNamePath, $level + 1);
            }

            $item = [
                'id' => $code,
                'code' => $code,
                'name' => $name,
                'full_name' => implode('/', $currentNamePath),
                'level' => $level,
            ];

            if ($children !== []) {
                $item['children'] = $children;
            }

            $result[] = $item;
        }

        return $result;
    }

    private function resolveFilePath(): string
    {
        $base = app()->getRootPath();
        $candidates = [
            $base . 'data/pcas-code.json',
            dirname($base) . '/server/data/pcas-code.json',
            dirname($base) . '/data/pcas-code.json',
            root_path() . 'server/data/pcas-code.json',
        ];

        foreach ($candidates as $file) {
            if ($file && is_file($file)) {
                return $file;
            }
        }

        return '';
    }
}
